<template>
  <div class="prediction">
    <el-card class="control-panel">
      <template #header>
        <div class="card-header">
          <span>预测控制</span>
          <div class="header-actions">
            <el-button type="primary" plain size="small" @click="goToDataManagement">
              <el-icon><Upload /></el-icon>
              管理数据
            </el-button>
          </div>
        </div>
      </template>
      
      <el-form :model="form" label-width="120px">
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="选择数据集">
              <el-select 
                v-model="form.dataset" 
                placeholder="请选择数据集"
                @change="handleDatasetChange"
              >
                <el-option
                  v-for="item in datasets"
                  :key="item.id"
                  :label="item.name"
                  :value="item.id"
                >
                  <div style="display: flex; justify-content: space-between; align-items: center">
                    <span>{{ item.name }}</span>
                    <el-tag size="small" :type="item.status === '已处理' ? 'success' : 'warning'">
                      {{ item.status }}
                    </el-tag>
                  </div>
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="序列长度">
              <el-input-number v-model="form.seq_len" :min="1" :max="1000" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="预测长度">
              <el-input-number v-model="form.pred_len" :min="1" :max="500" />
            </el-form-item>
          </el-col>
        </el-row>
        
        <el-row :gutter="20" style="margin-top: 20px">
          <el-col :span="12">
            <el-form-item label="数据插值">
              <div class="interpolation-group">
                <el-switch v-model="form.useInterpolation" />
                <el-input 
                  v-model="form.interpolationValue" 
                  placeholder="请输入插值间隔"
                  :disabled="!form.useInterpolation"
                  style="margin-left: 20px; width: 200px;"
                >
                  <template #append>分钟</template>
                </el-input>
              </div>
            </el-form-item>
          </el-col>
        </el-row>
        
        <el-row v-if="selectedDataset" class="dataset-info">
          <el-col :span="24">
            <el-descriptions :column="3" border size="small">
              <el-descriptions-item label="数据量">{{ selectedDataset.size }}</el-descriptions-item>
              <el-descriptions-item label="更新时间">{{ selectedDataset.updateTime }}</el-descriptions-item>
              <el-descriptions-item label="数据类型">{{ selectedDataset.type }}</el-descriptions-item>
            </el-descriptions>
          </el-col>
        </el-row>
        
        <el-form-item>
          <el-button type="primary" @click="startPrediction" :disabled="!form.dataset || predicting">
            开始预测
          </el-button>
          <el-button type="warning" @click="stopPrediction" :disabled="!predicting">
            停止预测
          </el-button>
          <el-button @click="resetForm">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <el-card class="result-panel" v-loading="loading">
      <template #header>
        <div class="card-header">
          <span>预测结果</span>
          <div class="feature-selector" v-if="featureNames.length > 0">
            <span>选择特征:</span>
            <el-select v-model="selectedFeature" placeholder="选择特征" size="small">
              <el-option
                v-for="feature in featureNames"
                :key="feature"
                :label="feature"
                :value="feature"
              />
            </el-select>
          </div>
        </div>
      </template>
      
      <div class="chart-container">
        <v-chart class="chart" :option="chartOption" autoresize />
      </div>
    </el-card>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Upload } from '@element-plus/icons-vue'
import { fileApi, predictionApi } from '@/api'
import { API_CONFIG } from '@/api/config'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { LineChart } from 'echarts/charts'
import {
  TitleComponent,
  TooltipComponent,
  LegendComponent,
  GridComponent,
  DataZoomComponent,
  ToolboxComponent
} from 'echarts/components'
import VChart from 'vue-echarts'

// 注册ECharts组件
use([
  CanvasRenderer,
  LineChart,
  TitleComponent,
  TooltipComponent,
  LegendComponent,
  GridComponent,
  DataZoomComponent,
  ToolboxComponent
])

const router = useRouter()

// 表单数据
const form = ref({
  dataset: '',
  type: '',
  duration: '',
  useInterpolation: false,
  interpolationValue: '',
  seq_len: 126,
  pred_len: 4
})

// 状态变量
const loading = ref(false)
const predicting = ref(false)
const wsClient = ref(null)
const datasets = ref([])
const featureNames = ref([])
const selectedFeature = ref('')

// 预测数据
const predictionData = ref({
  timestamps: [],
  values: {}
})

// 获取数据集列表
const fetchDatasets = async () => {
  try {
    const response = await fileApi.getFileList()
    if (response.files) {
      datasets.value = response.files.map(filename => ({
        id: filename,
        name: filename,
        type: filename.includes('load') ? '负荷数据' : 
              filename.includes('wind') ? '风电数据' : 
              filename.includes('solar') ? '光伏数据' : '其他',
        size: '未知',
        updateTime: new Date().toLocaleDateString(),
        status: filename.includes('processed') ? '已处理' : '处理中'
      }))
    }
  } catch (error) {
    ElMessage.error('获取数据集列表失败')
    console.error(error)
  }
}

// 图表配置
const chartOption = computed(() => {
  const series = []
  
  if (selectedFeature.value && predictionData.value.values[selectedFeature.value]) {
    series.push({
      name: selectedFeature.value,
      type: 'line',
      data: predictionData.value.values[selectedFeature.value],
      smooth: true
    })
  } else {
    // 如果没有选择特征，显示所有特征
    Object.keys(predictionData.value.values).forEach(feature => {
      series.push({
        name: feature,
        type: 'line',
        data: predictionData.value.values[feature],
        smooth: true
      })
    })
  }

  return {
    title: {
      text: '预测结果',
      left: 'center'
    },
    tooltip: {
      trigger: 'axis'
    },
    legend: {
      data: series.map(s => s.name),
      top: 30
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '10%',
      containLabel: true
    },
    toolbox: {
      feature: {
        saveAsImage: {}
      }
    },
    dataZoom: [
      {
        type: 'slider',
        show: true,
        start: 0,
        end: 100
      }
    ],
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: predictionData.value.timestamps
    },
    yAxis: {
      type: 'value'
    },
    series
  }
})

// 处理数据集选择变化
const handleDatasetChange = (value) => {
  const dataset = datasets.value.find(d => d.id === value)
  if (dataset) {
    form.value.type = dataset.type === '负荷数据' ? 'load' : 
                      dataset.type === '风电数据' ? 'wind' : 'solar'
  }
}

// 开始预测
const startPrediction = async () => {
  if (!form.value.dataset) {
    ElMessage.warning('请选择数据集')
    return
  }

  // 重置预测数据
  predictionData.value = {
    timestamps: [],
    values: {}
  }
  featureNames.value = []
  selectedFeature.value = ''
  
  loading.value = true
  predicting.value = true
  
  try {
    console.log('正在连接WebSocket...');
    // 创建一个新的WebSocket连接
    const ws = new WebSocket(API_CONFIG.PREDICTION.WS_URL);
    wsClient.value = ws; // 保存引用以便后续可以关闭连接
    
    ws.onopen = () => {
      console.log('WebSocket连接成功，发送配置...');
      // 发送预测请求
      const config = {
        data_file: form.value.dataset,
        seq_len: form.value.seq_len,
        pred_len: form.value.pred_len,
        use_gpu: true,
        export_format: 'csv'
      };
      console.log('发送配置:', config);
      ws.send(JSON.stringify(config));
    };
    
    // 处理消息
    ws.onmessage = (event) => {
      console.log('收到WebSocket消息:', event.data);
      try {
        const data = JSON.parse(event.data);
        
        // 处理元数据
        if (data.type === 'metadata') {
          console.log('收到元数据:', data);
          featureNames.value = data.features;
          
          // 初始化数据结构
          data.features.forEach(feature => {
            predictionData.value.values[feature] = [];
          });
          
          // 默认选择第一个特征
          if (data.features.length > 0) {
            selectedFeature.value = data.features[0];
          }
        } 
        // 处理预测完成
        else if (data.status === 'completed') {
          ElMessage.success('预测完成');
          loading.value = false;
          predicting.value = false;
          
          // 询问用户是否查看历史数据
          ElMessageBox.confirm(
            '预测已完成，是否查看历史预测数据？',
            '预测完成',
            {
              confirmButtonText: '查看历史',
              cancelButtonText: '留在当前页面',
              type: 'success'
            }
          )
          .then(() => {
            // 导航到仪表板页面
            router.push('/dashboard');
          })
          .catch(() => {
            // 用户选择留在当前页面，不做任何操作
          });
        } 
        // 处理错误
        else if (data.error) {
          let errorMsg = data.error;
          
          // 提供更友好的错误消息
          if (errorMsg.includes('时间间隔不一致')) {
            errorMsg = '数据集的时间间隔不一致，无法进行预测。请使用时间间隔一致的数据集。';
          }
          
          ElMessage.error(`预测错误: ${errorMsg}`);
          loading.value = false;
          predicting.value = false;
        } 
        // 处理预测数据
        else if (data.predictions && data.timestamps) {
          // 添加时间戳
          predictionData.value.timestamps.push(data.timestamps);
          
          // 添加各个特征的预测值
          data.predictions.forEach((value, index) => {
            const feature = featureNames.value[index];
            if (feature) {
              predictionData.value.values[feature].push(value);
            }
          });
        }
      } catch (error) {
        console.error('解析WebSocket消息失败:', error);
      }
    };
    
    // 处理错误
    ws.onerror = (error) => {
      console.error('WebSocket错误:', error);
      ElMessage.error('预测错误，请检查控制台日志');
      loading.value = false;
      predicting.value = false;
    };
    
    // 处理关闭
    ws.onclose = (event) => {
      console.log(`WebSocket连接关闭: 代码=${event.code}, 原因=${event.reason}`);
      if (predicting.value) {
        ElMessage.warning('WebSocket连接已关闭');
        loading.value = false;
        predicting.value = false;
      }
    };
  } catch (error) {
    console.error('启动预测失败:', error);
    ElMessage.error('启动预测失败');
    loading.value = false;
    predicting.value = false;
  }
};

// 停止预测
const stopPrediction = () => {
  if (wsClient.value && predicting.value) {
    wsClient.value.send('stop');
    wsClient.value.close();
    predicting.value = false;
    ElMessage.warning('已停止预测');
  }
};

// 重置表单
const resetForm = () => {
  form.value = {
    dataset: '',
    type: '',
    duration: '',
    useInterpolation: false,
    interpolationValue: '',
    seq_len: 126,
    pred_len: 4
  }
  predictionData.value = {
    timestamps: [],
    values: {}
  }
  featureNames.value = []
  selectedFeature.value = ''
}

// 跳转到数据管理
const goToDataManagement = () => {
  router.push('/data')
}

// 生命周期钩子
onMounted(() => {
  fetchDatasets()
})

onUnmounted(() => {
  if (wsClient.value) {
    wsClient.value.disconnect()
  }
})

// 计算属性
const selectedDataset = computed(() => {
  return datasets.value.find(d => d.id === form.value.dataset) || {}
})
</script>

<style scoped>
.prediction {
  padding: 20px;
}

.control-panel {
  margin-bottom: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.chart-container {
  height: 400px;
}

.chart {
  height: 100%;
  width: 100%;
}

.header-actions {
  display: flex;
  gap: 16px;
}

.dataset-info {
  margin: 20px 0;
}

.interpolation-group {
  display: flex;
  align-items: center;
}

.feature-selector {
  display: flex;
  align-items: center;
  gap: 10px;
}
</style> 